Skip to content

Conversation

@khaledalam
Copy link

Description

Fixes #10497 - Allows direct modification of object properties stored in constants.

Problem

Previously, this code would fail with a fatal error:

const a = new stdClass;
a->b = 42;  // Fatal error: Cannot use temporary expression in write context

Solution

Modified the compiler to properly handle ZEND_AST_CONST in variable compilation contexts:

Constants now emit IS_VAR instead of IS_TMP_VAR when used in write contexts
This allows property assignment opcodes to work correctly with constant objects

Tests:

  • Added Zend/tests/gh10497.phpt - comprehensive test for the fix
  • Updated Zend/tests/gh12102_3.phpt - reflects improved constant handling

Behavior

Now supports all property operations on constant objects:

const obj = new stdClass;
obj->prop = 'value';
obj->prop = 'new value';
obj->another = 'test';
obj->counter = 0;
obj->counter++;
obj->num = 10;
obj->num += 5;
unset(obj->prop);
obj->nested = new stdClass;
obj->nested->value = 123;

The constant reference remains immutable, but the object itself is mutable as expected.

Copy link
Member

@iluuu1994 iluuu1994 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @khaledalam! Looks reasonable overall.

Pass type parameter to zend_compile_const() instead of bool use_tmp
Check BP_VAR_R/BP_VAR_IS for read mode
Remove unnecessary wrapper function
Return void instead of zend_op*
@khaledalam
Copy link
Author

Thanks @khaledalam! Looks reasonable overall.

Thanks @iluuu1994 for the feedback, all comments addressed.

@iluuu1994
Copy link
Member

Cool, thanks @khaledalam! This is a language change and should be discussed on the internals mailing list at least. I think this will impact GH-13800, but that's not a major issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot directly modify an object stored in a constant

2 participants